import { ModalForm, ProForm, ProFormDigitRange, ProFormList } from "@ant-design/pro-components";
import { Button, Dropdown, Form, message, Spin } from "antd";
import { forwardRef, PropsWithChildren, useImperativeHandle, useState } from "react";
import EvaluationSelect, {
    Value as EvaluationSelectValue,
} from '@/components/EvaluationSelect';
import { css } from "@emotion/css";
import { useDebounceFn, useMemoizedFn, useRequest } from "ahooks";
import { eqV1ControllerGetFiltersBySegmentFreq } from "@/services/auto/eq";
import { EvaluationCategory } from "common/utils/data";
import FreqChartViewer, { Props as FreqChartViewerProps } from "./FreqChartViewer";
import { evaluationDataV1ControllerBatch } from "@/services/auto/articleData";
import { useModel } from "@umijs/max";
import { PlusCircleOutlined, PlusOutlined } from "@ant-design/icons";

export default forwardRef(function SegmentEQ({
    children,
    onConfirm,
    sourcePoints
}: PropsWithChildren<{
    onConfirm: (res: API.EQResultFilters[]) => void
    sourcePoints: number[][];
}>, ref: React.Ref<SegmentEQRef>) {
    const { data: globalConfigData } = useModel('global-config');

    const [openState, setOpenState] = useState(false);

    const outerForm = Form.useFormInstance();
    const [form] = Form.useForm<FormData>();

    const { runAsync } = useRequest(eqV1ControllerGetFiltersBySegmentFreq, {
        manual: true,
    });

    const { run: onValuesChange } = useDebounceFn(() => {
        setViewerDataSet(undefined);
        setViewerError(undefined);
        form.validateFields({
            validateOnly: true,
        }).then((values) => {
            getEvaluationData({
                list: values.segmentList.map(item => ({
                    evaluationUuid: item.target.evaluationUuid!,
                    group: item.target.dataGroup!,
                    projectUuid: 'cdcf35b6-f37c-4b77-877f-9b8ddbf38c5b',
                }))
            }).then(res => {
                const viewerDataSetListCurrent: typeof viewerDataSetList = [];
                values.segmentList.sort((a, b) => a.range[0] - b.range[0]).forEach((segmentItem, segmentIndex) => {
                    if (segmentIndex === 0) {
                        if (segmentItem.range[0] !== 20) {
                            viewerDataSetListCurrent.push({
                                dataSet: sourcePoints.filter(item => item[0] >= 20 && item[0] <= segmentItem.range[0]),
                                range: [20, segmentItem.range[0]],
                            })
                        }
                    }


                    const current = res.find(item => item.evaluationUuid === segmentItem.target.evaluationUuid && item.group === segmentItem.target.dataGroup);
                    if (current?.dataSet) {
                        const dataSet: number[][] = [];

                        current.dataSet.forEach((row, index) => {
                            if (index !== 0) {
                                const numberRow = row.map(Number);
                                if (numberRow[0]! >= segmentItem.range[0] && numberRow[0]! <= segmentItem.range[1]) {
                                    dataSet.push(numberRow);
                                }
                            }
                        })

                        viewerDataSetListCurrent.push({
                            brand: current.evaluation.brand.title,
                            title: current.evaluation.title,
                            dataGroup: current.group,
                            dataSet,
                            range: segmentItem.range,
                        })
                    }

                    if (segmentIndex >= 0 && segmentIndex < values.segmentList.length - 1) {
                        if (segmentItem.range[1] !== values.segmentList[segmentIndex + 1].range[0]) {
                            viewerDataSetListCurrent.push({
                                dataSet: sourcePoints.filter(item => item[0] >= segmentItem.range[1] && item[0] <= values.segmentList[segmentIndex + 1].range[0]),
                                range: [segmentItem.range[1], values.segmentList[segmentIndex + 1].range[0]],
                            })
                        }
                    }

                    if (segmentIndex === values.segmentList.length - 1) {
                        if (segmentItem.range[1] !== 20000) {
                            viewerDataSetListCurrent.push({
                                dataSet: sourcePoints.filter(item => item[0] >= segmentItem.range[1] && item[0] <= 20000),
                                range: [segmentItem.range[1], 20000],
                            })
                        }
                    }
                });

                setViewerDataSet(viewerDataSetListCurrent);
            })
        }).catch((error) => {
            if (error.errorFields?.length) {
                setViewerError(error.errorFields[0].errors.join('，'));
            }
        })
    }, {
        wait: 500,
    })

    const open = useMemoizedFn((initialValues?: Partial<FormData>) => {
        if (initialValues) {
            form.setFieldsValue(initialValues);
        }
        setOpenState(true);
    });

    useImperativeHandle(ref, () => ({
        open,
    }), []);

    const [viewerError, setViewerError] = useState<string>();

    const [viewerDataSetList, setViewerDataSet] = useState<FreqChartViewerProps['dataSetList']>();

    const { runAsync: getEvaluationData, loading: evaluationDataLoading } = useRequest(evaluationDataV1ControllerBatch, {
        manual: true,
    })

    return <ModalForm
        layout="horizontal"
        width={1200}
        open={openState}
        labelCol={{ style: { width: 100 } }}
        modalProps={{
            maskClosable: false,
            okButtonProps: {
                disabled: !viewerDataSetList?.length,
            }
        }}
        form={form}
        onValuesChange={() => {
            onValuesChange();
        }}
        onOpenChange={(val) => {
            setOpenState(val);
            if (val) {
                onValuesChange();
            } else {
                form.resetFields();
            }
        }}
        title="调音融合（多耳机拼接）"
        trigger={children as JSX.Element}
        onFinish={(values) => {
            const { segmentList } = values as FormData;
            const outerFormValues = outerForm.getFieldsValue();
            return runAsync({
                evaluationUuid: outerFormValues.current.evaluationUuid!,
                dataGroup: outerFormValues.current.dataGroup!,
                segmentList: viewerDataSetList!.map(viewerDataSetItem => {
                    const curSeg = segmentList.find(segmentItem => segmentItem.range[0] === viewerDataSetItem.range[0] && segmentItem.range[1] === viewerDataSetItem.range[1])
                    return {
                        start: viewerDataSetItem.range[0],
                        end: viewerDataSetItem.range[1],
                        ...(curSeg ? {
                            evaluationUuid: curSeg.target.evaluationUuid!,
                            dataGroup: curSeg.target.dataGroup!,
                        } : {
                            dataSet: viewerDataSetItem.dataSet,
                        })
                    }
                }),
            }).then(res => {
                message.success('融合成功');
                onConfirm(res.filters);
                return true;
            }).catch((e) => {
                console.error(e);
                return false;
            });
        }}
    >
        <ProFormList
            copyIconProps={false}
            label="分段设置"
            arrowSort
            name="segmentList"
            required
            max={5}
            min={1}
            initialValue={[
                {
                    id: `key-${Math.random().toString()}`,
                    target: undefined,
                    range: [20, 20000],
                },
            ]}
            creatorButtonProps={{
                position: 'bottom',
                creatorButtonText: '新增分段',
            }}
            creatorRecord={() => {
                const values = form.getFieldsValue()
                const lastRange = values.segmentList[values.segmentList.length - 1].range;
                return {
                    id: `key-${Math.random().toString()}`,
                    target: undefined,
                    range: lastRange[1] ? [lastRange[1], 20000] : undefined,
                }
            }}
            className={css({
                '& .ant-pro-form-list-item': {
                    alignItems: 'flex-start !important'
                },
            })}
            rules={[
                {
                    validator: (_, val: FormData['segmentList']) => {
                        // 检查所有range是否没有重叠并且相接
                        const ranges = val.map(item => item.range);
                        const validation = validateRanges(ranges);

                        if (!validation.isValid) {
                            return Promise.reject(new Error(validation.error));
                        }
                        return Promise.resolve();
                    },
                },
            ]}
        >
            {(meta) => {
                console.log(meta);
                return <div className="flex items-start gap-[8px]">
                {!!globalConfigData.presetSegmentFreq?.length && <Dropdown trigger={['click']} menu={{
                    items: globalConfigData.presetSegmentFreq.map(item => ({
                        label: item.name,
                        key: item.name,
                        onClick: () => {
                            form.setFieldValue(['segmentList',meta.name], {
                                target: {
                                    evaluationUuid: item.evaluationUuid,
                                    dataGroup: item.dataGroup,
                                },
                                range: [item.start, item.end],
                            });
                        },
                    })),
                }}><Button type="link">使用预设分段</Button></Dropdown>}
                <ProFormDigitRange placeholder={['起始频率', '结束频率']} name="range" fieldProps={{
                    precision: 0,
                    className: 'w-[100px]',
                }} rules={[
                    {
                        validator: (_, value: [number, number]) => {
                            if (!value[0]) {
                                return Promise.reject('请填写起始频率')
                            }
                            if (!value[1]) {
                                return Promise.reject('请填写结束频率')
                            }
                            if (value[0] < 20 || value[1] > 20000) {
                                return Promise.reject('频率范围必须在20-20000之间')
                            }
                            if (value[0] > value[1]) {
                                return Promise.reject('结束频率必须大于起始频率')
                            }
                            return Promise.resolve();
                        },
                    },
                ]} />
                <ProForm.Item className="w-[600px]" name="target" rules={[
                    {
                        validator: (_, value) => {
                            return EvaluationSelect.getValidator(value, true, true);
                        },
                    },
                ]}>
                    <EvaluationSelect category={EvaluationCategory.EARBUDS} withDataGroup />
                </ProForm.Item>
            </div>
            }}
        </ProFormList>
        {
            !!globalConfigData.presetSegmentFreq?.length && <Form.Item label=" " colon={false} className="mb-0">
                <div className="flex gap-[16px]">
                    {
                        globalConfigData.presetSegmentFreq.map(item => {
                            return <Button type="dashed" key={item.name} onClick={() => {
                                form.setFieldsValue({
                                    segmentList: form.getFieldsValue().segmentList.concat({
                                        id: Math.random.toString(),
                                        range: [item.start, item.end],
                                        target: {
                                            evaluationUuid: item.evaluationUuid,
                                            dataGroup: item.dataGroup,
                                        }
                                    })
                                })
                            }} icon={<PlusOutlined />}>
                                新增 {item.name}
                            </Button>
                        })
                    }
                </div>
            </Form.Item>

        }
        <Spin spinning={evaluationDataLoading}>
            <FreqChartViewer dataSetList={viewerDataSetList} error={viewerError} />
        </Spin>
    </ModalForm>
})

interface FormData {
    segmentList: {
        id: string;
        range: [number, number];
        target: EvaluationSelectValue<true>;
    }[];
}

// 验证range数组是否没有重叠并且相接
function validateRanges(ranges: [number | undefined, number | undefined][]): { isValid: boolean; error?: string } {
    if (ranges.length === 0 || ranges.some(range => range === undefined || range[0] === undefined || range[1] === undefined)) {
        return { isValid: true };
    }

    // 按起始频率排序
    const sortedRanges = [...ranges].sort((a, b) => a[0]! - b[0]!);

    // 检查是否有重叠
    for (let i = 0; i < sortedRanges.length - 1; i++) {
        const current = sortedRanges[i];
        const next = sortedRanges[i + 1];

        // 检查重叠：当前范围的结束频率 > 下一个范围的起始频率
        if (current[1]! > next[0]!) {
            return {
                isValid: false,
                error: `第${i + 1}个和第${i + 2}个频率范围有重叠`
            };
        }
    }

    // // 检查是否相接
    // for (let i = 0; i < sortedRanges.length - 1; i++) {
    //     const current = sortedRanges[i];
    //     const next = sortedRanges[i + 1];

    //     // 检查相接：当前范围的结束频率应该等于下一个范围的起始频率
    //     if (current[1]! !== next[0]!) {
    //         return {
    //             isValid: false,
    //             error: `第${i + 1}个和第${i + 2}个频率范围不相接`
    //         };
    //     }
    // }

    return { isValid: true };
}


export interface SegmentEQRef {
    open: (initialValues?: Partial<FormData>) => void;
}